package spitzer.flair.views;


import java.util.Iterator;
import java.util.Vector;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.part.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.action.*;
import org.eclipse.ui.*;
import org.eclipse.swt.SWT;

import spitzer.flair.FlashPlugin;
import spitzer.flair.preferences.FlairPreferenceConstants;
import spitzer.flair.widgets.FlashPlayer;


/**
 * This sample class demonstrates how to plug-in a new
 * workbench view. 
 */

public class SWFView extends ViewPart {
	private Action actionRefresh;
	private Action actionLoad;
	private Shell shell;
	private Recents recents;

	private String swfPath;
	private FlashPlayer player;

	/**
	 * Maintains the list of recently viewed files in preference
	 * store, provides menu listener to fill toolbar menu.  
	 */
	private class Recents implements IMenuListener {
		class RecentItemAction extends Action {
			private String actionSWFPath;
			
			public RecentItemAction(String path) {
				this.actionSWFPath = path;	
				// leave only filename.. no - full path is better
				// setText(path.replaceFirst("", ""));
				setText(path);
			}
			public void run() {
				loadMovie(actionSWFPath);
			}
		}
		
		private Vector<String> recentItems;
		private int maxRecents;
		
		public Recents() {
			IPreferenceStore ps = FlashPlugin.getDefault().getPreferenceStore();
			maxRecents = ps.getInt(FlairPreferenceConstants.P_MAX_RECENTS);

			recentItems = new Vector<String>(maxRecents);
		}

		/** Adds path as most recent item **/
		public void add(String path) {
			if (recentItems.contains(path)){
				recentItems.remove(path);
			}
			recentItems.add(0, path);
			if (recentItems.size() > maxRecents) {
				recentItems.setSize(maxRecents);
			}
		}
		/** @return full path or null if no recent item	**/
		public String getMostRecent() {
			if (recentItems.isEmpty()) {
				return null;
			} else {
				return recentItems.firstElement();
			}
		}

		public void menuAboutToShow(IMenuManager manager) {
			manager.add(new Separator());
			for (Iterator<String> rit = recentItems.iterator(); rit.hasNext();) {
				manager.add(new RecentItemAction(rit.next()));
			}
			/** TODO
			manager.add(actionRefresh);
			manager.add(new Separator());
			manager.add(actionLoad);
			**/
		}
		public void saveState(IMemento memento) {
			// there is a way to use JAXB or xstream, but it's an overkill
			for (int i=0; i<recentItems.size(); i++) {
				memento.putString("i"+i, recentItems.get(i));
			}
		}
		public void restoreState(IMemento memento) {
			// there is a way to use JAXB or xstream, but it's an overkill
			String str;
			for (int i=0; i<maxRecents; i++) {
				str = memento.getString("i"+i);
				if (str == null) {
					break;
				} else {
					recentItems.add(i, str);
				}
			}
		}
	}
	

	// save/restore state between sessions
	@Override
	public void saveState(IMemento memento) {
		// save state to memento
		recents.saveState(memento.createChild("recents"));		
	}
	// init() is called before createPartControl()
	@Override
	public void	init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		//System.out.print("init\n");
		// restore state from memento
        recents = new Recents();
        if (memento != null) {
	        IMemento m = memento.getChild("recents");
	        if (m != null) {
	        	recents.restoreState(m);
	        }
        }
	}

	/**
	 * The constructor.
	 */
	public SWFView() {
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
        shell = parent.getShell();
		//System.out.print("create part\n");
        
        player = new FlashPlayer(parent, 0);
        
		makeActions();
		fillLocalToolBar();
		fillLocalPullDown();
		
        String latest = recents.getMostRecent();
        if (latest != null) {
        	loadMovie(latest);
        }
	}

	private void fillLocalPullDown() {
		//System.out.print("pullDown\n");
		IMenuManager manager = getViewSite().getActionBars().getMenuManager();
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(recents);
		// add something to enable menu 
		manager.add(new Separator());
	}

	private void fillLocalToolBar() {
		IToolBarManager manager = getViewSite().getActionBars().getToolBarManager();
		manager.add(actionLoad);
		manager.add(actionRefresh);
	}

	private void makeActions() {
		
		actionRefresh = new Action() {
			public void run() {
				refreshView();
			}
		};
		actionRefresh.setText("Refresh");
		actionRefresh.setToolTipText("Reload current SWF");
		actionRefresh.setImageDescriptor(
				FlashPlugin.getImageDescriptor("icons/elcl16/refresh.gif"));

		actionLoad = new Action() {
			public void run() {
				chooseSWFDialog();
			}
		};
		actionLoad.setText("Load SWF");
		actionLoad.setToolTipText("Specify SWF to view");
		actionLoad.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
				getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER));
	}
	
	protected void loadMovie(String path) {
		swfPath = path;
		recents.add(path);
		player.setMovie(swfPath);
	}


	protected void refreshView() {
		player.setMovie(swfPath);
	}


	private static final String[] filterExtensions = {
		"*.swf",
		"*.*"};
	private static final String[] filterNames  = {
	    "Adobe Flash (*.swf)",
	    "All Files (*.*)"};
	protected void chooseSWFDialog() {
		FileDialog dialog = new FileDialog(shell, SWT.OPEN);
		dialog.setFilterExtensions(filterExtensions);
		dialog.setFilterNames(filterNames);
		String path = dialog.open();
		if (path != null) {
			loadMovie(path);
		}
	}
	

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
	}
}